#include"../logs/bitlog.h"
#include<unistd.h>

/*
    扩展一个一时间作为文件滚动切换类型的日志落地模块
    1.一时间进行文件滚动，实际上是以时间段进行滚动
        实现思想： 以当前系统时间，取模时间段大小，可以得到当前时间段是第几个时间段
                    每次以当前系统时间取模，判断与当前文件的时间段是否一致，不一致代表不是一个时间段
    time(nullptr)%60  = 10  当前就是第n个60s
*/

enum class TimeGap{
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY,
};

 class RollByTimeSink:public bitlog::LogSink{
        public:
        //构造时传入文件名，并打开文件，将操作句柄管理起来
        RollByTimeSink(const std::string &basename,TimeGap gap_type):_basename(basename){
            switch (gap_type)
            {
            case TimeGap::GAP_SECOND: _gap_size=1;break;
            case TimeGap::GAP_MINUTE: _gap_size=60;break;
            case TimeGap::GAP_HOUR: _gap_size=3600;break;
            case TimeGap::GAP_DAY: _gap_size=3600*24;break;
            } 
            _cur_gap=_gap_size==1?bitlog::util::Date::now() :bitlog::util::Date::now()%_gap_size;//获取当前是第几个时间段
            std::string filename=createNewFile();
            bitlog::util::File::createDirectory(bitlog::util::File::path(filename));
            _ofs.open(filename,std::ios::binary|std::ios::app);
            assert(_ofs.is_open());
        }
        //将日志消息写入到标准输出，判断当前时间是否是当前文件的时间段，不是则切换文件
        void log(const char *data,size_t len)
        {
            time_t cur=bitlog::util::Date::now();
            if((cur%_gap_size)!=_cur_gap)
            {
                _ofs.close();
                std::string filename=createNewFile();
                _ofs.open(filename,std::ios::binary|std::ios::app);
                assert(_ofs.is_open());
            }
            _ofs.write(data,len);
            assert(_ofs.good());
        }
        private:
        std::string createNewFile(){
            time_t t=bitlog::util::Date::now();
                struct tm lt;
                localtime_r(&t,&lt);
                std::stringstream filename;
                filename << _basename;
                filename << lt.tm_year+1900;
                filename <<lt.tm_mon+1;
                filename<<lt.tm_mday;
                filename << lt.tm_hour;
                filename <<lt.tm_min;
                filename<<lt.tm_sec;
                filename<<".log";    //文件后缀名
                return filename.str();   
        }

        private:
        std::string _basename;
            std::string _pathname;
            std::ofstream _ofs;        //输出的时候可以直接通过句柄进行输出，不用每次先写入消息打开文件和关闭文件
            size_t _cur_gap;//当前是第几个时间段
            size_t _gap_size;//时间段的大小
    };

int main()
{
    std::unique_ptr<bitlog::LoggerBuilder>builder(new bitlog::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerLevel(bitlog::LogLevel::value::WARN);
    builder->buildFormatter("[%c][%f:%l]%m%n");
    builder->buildLoggerType(bitlog::LoggerType::LOGGER_ASYNC);
    builder->buildSink<RollByTimeSink>("./logfile/roll-async-by-time",TimeGap::GAP_SECOND);
    bitlog::Logger::ptr logger=builder->build();
    size_t cur=bitlog::util::Date::now();
    while(bitlog::util::Date::now()<cur+5)
    {
        logger->fatal("这是一条测试日志");
        usleep(1000);
    }
    return 0;
}